import jsonpath
import json
import re
from src.logger import logger

def parse_json(json_str):
    """解析JSON字符串为字典"""
    try:
        if isinstance(json_str, str) and json_str.strip():
            return json.loads(json_str)
        return json_str
    except Exception as e:
        logger.error(f"JSON解析失败: {str(e)}, 原始字符串: {json_str}")
        return None

def extract_value(response_json, expr):
    """
    从响应JSON中提取值
    :param response_json: 响应的JSON对象
    :param expr: jsonpath表达式
    :return: 提取的值
    """
    try:
        if not expr:
            return None
            
        result = jsonpath.jsonpath(response_json, expr)
        return result[0] if result else None
    except Exception as e:
        logger.error(f"提取值失败: {str(e)}, 表达式: {expr}")
        return None

def compare_response(actual_response, expected_str):
    """
    增强版响应验证：支持数组、正则匹配、数值比较
    actual_response: requests.Response 对象
    expected_str: Excel中expected_response列的字符串（如{"length": 3, "0.url": ".+"}）
    """
    try:
        actual = actual_response.json()  # 实际响应（可能是数组或字典）
        expected = parse_json(expected_str)  # 期望结果（字典）
        if not expected:
            return True, "无期望验证条件"

        # 1. 验证数组长度（通过expected中的"length"字段）
        if "length" in expected:
            actual_len = len(actual) if isinstance(actual, (list, tuple)) else 1 # 三元表达式
            if actual_len != int(expected["length"]):
                return False, f"数组长度不匹配，期望: {expected['length']}, 实际: {actual_len}"

        # 2. 验证字段：获取实际值actual_val（支持数组索引，如"0.url"表示数组第0个元素的url）
        for key, expected_val in expected.items():
            if key == "length":
                continue  # 过滤length判断，已处理长度验证

            # 解析数组索引（如"0.url" -> 索引0 + 字段url）
            if "." in key:
                index_str, field = key.split(".", 1)
                try:
                    index = int(index_str)
                    actual_val = actual[index][field]  # 取数组中第index个元素的field字段
                except (IndexError, KeyError) as e:
                    return False, f"字段 {key} 不存在: {str(e)}"
            else:
                # 非数组字段（直接取字典值）
                if key not in actual:
                    return False, f"字段 {key} 不存在于响应中"
                actual_val = actual[key]

            # 3. 验证规则：支持正则、数值比较（>、<、>=、<=）
            if isinstance(expected_val, str) and expected_val.startswith(("+", "-", ">", "<")):
                # 数值比较（如">0"表示实际值需大于0）
                op = expected_val[0]
                threshold = float(expected_val[1:])
                actual_num = float(actual_val)
                if op == ">" and not (actual_num > threshold):
                    return False, f"字段 {key} 不满足 {expected_val}，实际: {actual_num}"
                elif op == "<" and not (actual_num < threshold):
                    return False, f"字段 {key} 不满足 {expected_val}，实际: {actual_num}"
                # 可扩展 >=、<= 等逻辑
            elif  isinstance(expected_val, str):
                # 正则匹配（如".+"匹配任意字符串，非字符串：数字、布尔、None）re.fullmatch精准匹配
                if re.fullmatch(str(expected_val), str(actual_val)) is None:
                    return False, f"字段 {key} 不匹配，期望: {expected_val}, 实际: {actual_val}"
            else:
                # 精确匹配
                if actual_val != expected_val:
                    return False, f"字段 {key} 不匹配，期望: {expected_val}, 实际: {actual_val}"

        return True, "响应验证通过"
    except Exception as e:
        return False, f"验证失败: {str(e)}"